package jam.network.message;

import jam.model.*;
import jam.network.*;
import java.util.*;

//
// =============================================================================
//

public class ClientActionMessage extends ClientCommand {
    protected static final String KEYWORD = "CA_MSG";
    
    private String message;
    private String channelName;
    
    //
    // =========================================================================
    //
    
    /**
     * Processes the message, relaying it to other users.
     */
    @Override
    public void process(ClientController controller) {
        NetworkController network = controller.getNetworkController();
        ClientModel client = controller.getModel();
        ServerModel server = network.getModel();                
          
        // Check if this channel exists. Also prevents users from joining
        // channels they aren't in.
        Channel channel = client.getChannel(this.channelName);
        if (channel == null) {
            controller.send(new ServerResponse(this, false));
            return; // maybe throw an exception instead?
        }
        
        // Relay the message to other users in the channel.
        Set<String> users = channel.getUsers();
        synchronized(users) {
	        for (String user: users) {
	            if (user.equalsIgnoreCase(client.getUser().getUsername()))
	                continue;
	                
	            ClientController userController = server.getLoggedInMap().get(user);
	            userController.send(new ServerActionMessage(
	                userController.getNextTransactionId(),
	                this.channelName,
	                client.getUser().getUsername(),
	                this.message));
	        }                
        }
        
        // Respond to the first client.
        controller.send(new ServerResponse(this, true));
    }
    
    //
    // =========================================================================
    //
    
    @Override
    protected String getKeyword() { 
        return ClientActionMessage.KEYWORD; 
    }
    
    //
    // =========================================================================
    //
    
    /**
     * Constructor. Processes the data string.
     *
     * @param transactionId The identification number for this particular message.
     * @param args A scanner with the arguments
     */
    protected ClientActionMessage(int transactionId, Scanner args) {
        super(transactionId);
        
        // Grab the channel name.
        this.channelName = args.next();
        
        // Build the string, allowing colons.
        StringBuilder sb = new StringBuilder(args.next());
        while (args.hasNext() == true)
            sb.append(String.format(":%s", args.next()));                
        this.message = sb.toString();
    }
}